#ifndef NODE_RTS_HH_
# define NODE_RTS_HH_

# include <math/vector.hh>
# include <tools/list.hh>

# include <list>

# include "../physic/object.hh"
# include "functor.hh"
# include "../map/map.hh"

struct dynamic_node
{
  char is_surface; // 1 => surface
  char is_full_empty; // 1 => full, 0 => empty
  unsigned char position; // 6bits de position 3D
};

struct dyn_value
{
  char is_full_empty[8];
  List<dynamic_node*>* obj_list;
};

struct static_node_obj
{
  char is_surface; // 1 => surface
  char is_full_empty; // 1 => full, 0 => empty
  List<Object*>* obj_list; // liste d'objets des nodes >= 16 et dynamic_node == 8
};

class NodeRts
{
public:
  NodeRts ();
  ~NodeRts ();

  // ajout et destruction d'objets de l'octree
  void add_obj (Object* obj);
  bool delete_obj (Object* obj);  // true = reussi, false = non reussi

  // test de physique dans l'octree
  void accept (PhysicFunctor* phy);
  // affichage des objets
  void accept (DisplayFunctor* disp);
  // affichage des surfaces
  void accept (MapFunctor* mf);
  // on veut envoyer des objects a un client contenu dans le block de 128 en pos
  void accept (GetObjectFunctor* objf, Vector2d* pos);

  // insertion de la map dans l'octree
  void insert_map (Map* map, int offset_i, int offset_j);
protected:
  const int NB_NODE_256_TO_8; // nombre de noeuds entre 256 et 8 inclus
  const int INDEX_8; // premier noeud de taille 8
  const int INDEX_16; // premier noeud de taille 16
  const int INDEX_32; // premier noeud de taille 32
  const int INDEX_64; // premier noeud de taille 64
  const int INDEX_128; // premier noeud de taille 128

  // on met l'octree en etat stable pour les noeuds de 8
  void merge_surfaces (Map* map, int offset_i, int offset_j);

  // on merge les niveaux de 16 jusqu'a 256
  void merge_up ();

  // on envoie au client un block de taille 8 pour la map
  void send_node_8 (Vector3d pos, MapFunctor* mf);


  static_node_obj* static_tab_;
};

#endif /// !NODE_RTS_HH_
